package FrameWork.EventBus;

import FrameWork.EventBus.Anno.Actor;
import FrameWork.EventBus.Anno.Receiver;
import FrameWork.EventBus.Anno.Schedule;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;

@Component
public class RegisterReceiverConfigure implements BeanPostProcessor{

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //判断是否是actor
        final boolean isActor = bean.getClass().isAnnotationPresent(Actor.class);
        if (isActor){
            EventBusManager.registerActor(bean);
        }
        ReflectionUtils.doWithMethods(bean.getClass(), method -> {
            if (!method.isAnnotationPresent(Receiver.class) || !validMethod(method)){
                return;
            }
            //validMethod()方法做了类型判断，因此这个转换是安全的
            Class<? extends IEvent> eventType = method.getParameterTypes()[0].asSubclass(IEvent.class);
            //判断调度类型
            ScheduleType scheduleType = isActor? ScheduleType.ACTOR : ScheduleType.INHERIT;
            if (method.isAnnotationPresent(Schedule.class)){
                scheduleType = method.getAnnotation(Schedule.class).value();
            }
            EventBusManager.registerHandler(eventType,method,bean,scheduleType);
        });
        return bean;
    }

    private boolean validMethod(Method method){
        return method.getParameterTypes().length == 1 && IEvent.class.isAssignableFrom(method.getParameterTypes()[0]);
    }
}
